<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3-React生命周期（新）</title>
    <style>

    </style>
</head>
<body>
<!--准备好一个容器-->
<div id="root"></div>
<div id="root2"></div>

<!--引入React核心库-->
<script type="text/javascript" src="../0-ReactJs-v17.0.2/react.development.js"></script>
<!--引入React-Dom，用于支持React操作Dom-->
<script type="text/javascript" src="../0-ReactJs-v17.0.2/react-dom.development.js"></script>
<!--引入babel，用于将jsx转为js-->
<script type="text/javascript" src="../0-ReactJs-v17.0.2/babel.min.js"></script>

<script type="text/babel">

    /*
        1-初始化阶段：由ReactDOM.render()触发---初次渲染
                1.constructor()
                2.static getDerivedStateFromProps()
                3.render()  *必须使用的一个
                4.componentDidMount()   *常用，一般在这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息
        2-更新阶段：由组件内部this.setState()或父组件重新render触发
                1.static getDerivedStateFromProps()
                2.shouldComponentUpdate()
                3.render()  *必须使用的一个
                4.getSnapshotBeforeUpdate()
                4.componentDidUpdate()
        3-卸载组件：由ReactDOM.unmountComponentAtNode()触发
                1.componentWillUnmount()    *常用，一般这个钩子中做一些收尾工作，例如：关闭定时器、取消订阅消息
     */

    //创建组件
    class Count extends React.Component {

        constructor(props) {
            console.log('Count---constructor')
            super(props);
            this.state = {
                count: 0
            }
        }

        add = () => {
            //获取原状态
            const {count} = this.state
            //更新状态
            this.setState({
                count: count + 1
            })
        }

        death = () => {
            ReactDOM.unmountComponentAtNode(document.getElementById('root'))
        }

        force = () => {
            this.forceUpdate()
        }

        // //组件将要挂载
        // UNSAFE_componentWillMount() {
        //     console.log('Count---componentWillMount')
        // }

        //组件挂载完毕
        componentDidMount() {
            console.log('Count---componentDidMount')
        }

        //组件将要卸载
        componentWillUnmount() {
            console.log('Count---componentWillUnmount')
        }

        //若state的值在任何时候都取决于props，那可以使用getDerivedStateFromProps
        static getDerivedStateFromProps(props,state) {
            console.log('Count---getDerivedStateFromProps',props,state)
            return null;
            // return {count:100};
            // return props;
        }

        //在更新之前获取快照
        getSnapshotBeforeUpdate(preProps,preState) {
            console.log('Count---getSnapshotBeforeUpdate',preProps,preState)
            // return null;
            return "anyValue"
        }

        //控制组件更新的"阀门"
        shouldComponentUpdate() {
            console.log('Count---shouldComponentUpdate')
            return true;
        }

        // //组件将要更新的钩子
        // UNSAFE_componentWillUpdate() {
        //     console.log('Count---componentWillUpdate')
        // }

        //组件更新完成的钩子
        componentDidUpdate(preProps,preState,snapshotValue) {
            console.log('Count---componentDidUpdate',preProps,preState,snapshotValue)
        }

        //render调用的时机：初始化渲染、状态更新之后
        render() {
            console.log('Count---render')
            const {count} = this.state
            return (
                <div>
                    <h2>当前求和为:{count}</h2>
                    <button onClick={this.add}>点我+1</button>
                    <button onClick={this.death}>卸载组件</button>
                    <button onClick={this.force}>不更改任何状态中的数据，强制更新</button>
                </div>
            )
        }

    }

    /*
        class A extends React.Component {

            state = {carName: '奔驰'}

            changeCar = () => {
                this.setState({
                    carName: '奥拓'
                })
            }

            render() {
                return (
                    <div>
                        <div>我是A组件</div>
                        <button onClick={this.changeCar}>换车</button>
                        <B carName={this.state.carName}/>
                    </div>
                )
            }
        }

        class B extends React.Component {

            // //组件将要接收新的props的钩子
            // UNSAFE_componentWillReceiveProps() {
            //     console.log('B---componentWillReceiveProps')
            // }

            render() {
                console.log('B---render')
                return (
                    <div>我是B组件，接收到的车是{this.props.carName}</div>
                )
            }
        }
        */

    //渲染组件到页面
    ReactDOM.render(<Count count={80}/>, document.getElementById('root'));
    // ReactDOM.render(<A/>, document.getElementById('root2'));
</script>

</body>
</html>
